namespace chatroom
{
    class MessageStorgeTable{
        public:
            using Ptr = std::shared_ptr<MessageStorgeTable>;
            MessageStorgeTable(std::shared_ptr<odb::core::database>& db):_db(db){}
            //新增消息
            bool insert(const chatroom::message& msg)
            {
                try{
                    //开启事务
                    odb::transaction t(_db->begin());
                    _db->persist(msg);
                    t.commit();
                }catch(std::exception& e){
                    Logger_ERROR("新增消息失败{}-{}",msg.get_message_id(),e.what());
                    return false;
                }
                return true;
            }
            bool remove(const std::string& ssid)
            {
                try{
                    //开启事务
                    odb::transaction t(_db->begin());
                    typedef odb::query<chatroom::message> query;
                    typedef odb::result<chatroom::message> result;
                    _db->erase_query<chatroom::message>(query::session_id == ssid);
                    t.commit();
                }catch(std::exception& e){
                    Logger_ERROR("通过消息ID获取消息失败{}",message_id);
                    return false;
                }
            }
            //根据消息ID获取消息
            chatroom::message get_message(const std::string& message_id)
            {
                try{
                    //开启事务
                    odb::transaction t(_db->begin());
                    typedef odb::query<chatroom::message> query;
                    typedef odb::result<chatroom::message> result;
                    auto ret = _db->query<chatroom::message>(query::message_id == message_id);
                    t.commit();
                }catch(std::exception& e){
                    Logger_ERROR("通过消息ID获取消息失败{}",message_id);
                    return chatroom::message();
                }
                return *ret;
            }
            //获取时间段内的信息
            std::vector<chatroom::message> get_range_message(const std::string& ssid,const boost::posix_time::ptime ctime,const boost::posix_time::ptime etime){
                std::vector<chatroom::message> res;
                try{
                    //开启事务
                    odb::transaction t(_db->begin());
                    typedef odb::query<chatroom::message> query;
                    typedef odb::result<chatroom::message> result;
                    result r(_db->query<chatroom::message>(query::session_id == ssid && query::created_time >= ctime && query::created_time <= etime));
                    for(auto i(r.begin()); i != r.end(); ++i)
                    {
                        res.push_back(*i);
                    }
                    t.commit();
                }catch(std::exception& e){
                    Logger_ERROR("查询某个时间段内的消息失败{}-{}",boost::posix_time::ptime::to_simple_string(ctime),
                    ,boost::posix_time::ptime::to_simple_string(etime));
                    return res;
                }
                return res;
            }
            //获取最近N段的时间 消息数量，获取最近的 N 条消息(逆序+limit 即可)
            std::vector<chatroom::message> get_recent_message(const std::string& ssid,int count){
                std::vector<chatroom::message> res;
                try{
                    //开启事务
                    odb::transaction t(_db->begin());
                    typedef odb::query<chatroom::message> query;
                    typedef odb::result<chatroom::message> result;
                    stringstream ss;
                    ss << "session_id = '" << ssid << "' ";
                    ss << "order by created_time desc limit " << count;
                    std::string condition = ss.str(); 
                    result r(_db->query<chatroom::message>(condition));
                    for(auto i(r.begin()); i != r.end(); ++i)
                    {
                        res.push_back(*i);
                    }
                    t.commit();
                }catch(std::exception& e){
                    Logger_ERROR("查询最近N条消息失败{}-{}",ssid,e.waht());
                    return res;
                }
                return res;
            }
        private:
            std::shared_ptr<odb::core::database> _db
    };
}